package cn.test.comm;

import cn.hutool.core.convert.Convert;
import cn.virens.common.apifox.ApifoxDoc;
import cn.virens.common.entity.BaseModel;
import cn.virens.common.service.dubbo.BaseWriteProvider;
import cn.virens.common.utils.Assert;
import cn.virens.common.web.BaseJSONController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;

/**
 * 通用控制器-DataTable
 *
 * @作者 :cn.virens
 * @创建时间 :2016年10月13日 下午1:10:43
 */
public abstract class BaseTableController<T extends BaseModel, S extends BaseWriteProvider<T>> extends BaseJSONController {
    /**
     * 禁用所有接口
     */
    protected static final int DISABLED = 0x0000;

    /**
     * 启用添加接口
     */
    protected static final int CREATE = 0x0001;

    /**
     * 启用编辑接口
     */
    protected static final int UPDATE = 0x0010;

    /**
     * 启用删除接口
     */
    protected static final int DELETE = 0x0100;

    /**
     * 启用查看接口
     */
    protected static final int VIEW = 0x1000;

    protected @Autowired S mBaseService;

    /**
     * 接口启用标志位
     */
    private int enableSymbol = 0x0000;

    public BaseTableController(String identity) {
        this(identity, VIEW | CREATE | UPDATE | DELETE);
    }

    /**
     * 构造类
     *
     * @param identity     授权标识符
     * @param enableSymbol 接口状态
     */
    public BaseTableController(String identity, int enableSymbol) {
        this.enableSymbol = enableSymbol;
    }

    /**
     * 获取数据接口
     *
     * @param request
     * @param model
     * @return
     */
    @ResponseBody
    @RequestMapping("list.json")
    @ApifoxDoc(name = "列表", query = {"limit,10,每页条数", "page,1,当前页码"})
    public Model list(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
        return renderFail(model, "该接口未开放");
    }

    @ResponseBody
    @RequestMapping(value = "view.json")
    @ApifoxDoc(name = "查看", query = {"id,,唯一值"})
    public Model view(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("id") String id) throws Exception {
        return viewHandle(request, model, Assert.isEmpty(id, "参数为空"));
    }

    /**
     * 添加数据接口
     */
    @ResponseBody
    @ApifoxDoc(name = "创建")
    @RequestMapping(value = "create.json", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public Model createJSON(HttpServletRequest request, HttpServletResponse response, Model model, @RequestBody T record, BindingResult result) throws Exception {
        return createHandle(request, model, record);
    }

    /**
     * 修改数据接口
     */
    @ResponseBody
    @ApifoxDoc(name = "更新", query = {"id,,唯一值"})
    @RequestMapping(value = "update.json", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public Model updateJSON(HttpServletRequest request, HttpServletResponse response, Model model, @RequestBody T record, BindingResult result) throws Exception {
        return updateHandle(request, model, record);
    }

    /**
     * 删除数据接口
     *
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "delete.json")
    @ApifoxDoc(name = "删除", query = {"id,,唯一值"})
    public Model delete(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("id") String id) throws Exception {
        return deleteHandle(request, model, Assert.isEmpty(id, "参数为空"));
    }

    /**
     * 添加一条记录
     *
     * @param request 请求
     * @param model   返回
     * @param record  数据
     * @return
     */
    protected Model createHandle(HttpServletRequest request, Model model, T record) throws Exception {
        if (mBaseService.insert(record) != null) {
            return renderSuccess(model, "添加成功");
        } else {
            return renderFail(model, "添加失败");
        }
    }

    /**
     * 更新一条记录
     *
     * @param request 请求
     * @param model   返回
     * @param record  数据
     * @return
     */

    protected Model updateHandle(HttpServletRequest request, Model model, T record) throws Exception {
        if (mBaseService.update(record) != null) {
            return renderSuccess(model, "更新成功");
        } else {
            return renderFail(model, "更新失败");
        }
    }

    /**
     * 删除
     *
     * @param request 请求
     * @param model   返回
     * @param id      主键数组
     * @return
     */
    protected Model deleteHandle(HttpServletRequest request, Model model, String id) throws Exception {
        if (mBaseService.delete(toId(id)) > 0) {
            return renderSuccess(model, "删除成功");
        } else {
            return renderFail(model, "删除失败");
        }
    }

    /**
     * 查看
     *
     * @param request 请求
     * @param model   返回
     * @param id      主键数组
     * @return
     */
    protected Model viewHandle(HttpServletRequest request, Model model, String id) throws Exception {
        return renderSuccess(mBaseService.selectOne(toId(id)), model);
    }

    /**
     * 获取 指定接口是否启用
     *
     * @param target 接口标识
     * @return
     */
    protected final boolean enable(int target) {
        return (enableSymbol & target) == target;
    }

    /**
     * ID 转换
     *
     * @param id
     * @return
     */
    protected Serializable toId(String id) {
        return Convert.toLong(id, null);
    }
}
